﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MengCC.App.Hubs;
using MengCC.App.Models;
using MengCC.Core.Data;
using MengCC.Core.IO;
using MengCC.Core.Plugins;
using MengCC.Core.Projects;
using MengCC.Core.Works;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.SignalR;

namespace MengCC.App.Controllers
{
    public class ProjectsController : Controller
    {
        private readonly IHubContext<IOHub> iohub;
        private ProjectManager projectManager;
        private readonly WorkManager workManager;
        private readonly IOManager iOManager;

        public ProjectsController(IHubContext<IOHub> iohub, ProjectManager projectManager, WorkManager workManager, IOManager iOManager)
        {
            this.iohub = iohub;
            this.projectManager = projectManager;
            this.workManager = workManager;
            this.iOManager = iOManager;
        }

        public async Task<IActionResult> Index()
        {
            ViewBag.Projects = projectManager.GetProjects(0).ToList();
            return View();
        }
        public async Task<IActionResult> Add()
        {
            return View();
        }
        public async Task<IActionResult> Details(int projectid)
        {
            ViewBag.Project = projectManager.GetProject(projectid);
            ViewBag.Buildlogs = projectManager.GetBuildLogs(projectid, 1, 20).Items;

            return View();
        }
        public async Task<IActionResult> Edit(int projectid)
        {
            ViewBag.projectid = projectid;
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> AddProject(Project project)
        {
            if (!projectManager.IsNameAndCodeAvailable(project))
            {
                return new JsonResult(new Output
                {
                    code = 0,
                    msg="exist same name or code"
                });
            }
            projectManager.AddProject(project);
            return new JsonResult(new Output
            {
                code = 1
            });
        }
        [HttpPost]
        public async Task<IActionResult> EditProject(Project project)
        {
            if (!projectManager.IsNameAndCodeAvailable(project))
            {
                return new JsonResult(new Output
                {
                    code = 0,
                    msg = "exist same name or code"
                });
            }
            projectManager.UpdateProject(project);
            return new JsonResult(new Output
            {
                code = 1
            });
        }
        [HttpGet]
        public async Task<IActionResult> GetProject(int projectid)
        {
            var project = projectManager.GetProject(projectid);
            return new JsonResult(new Output<Project>
            {
                code = 1,
                data = project
            });
        }

        [HttpPost]
        public async Task<IActionResult> BuildProject(int projectid)
        {

            workManager.StartWork(projectid);
            return new JsonResult(new Output
            {
                code = 1
            });
        }
        /// <summary>
        /// 远程构建
        /// </summary>
        /// <param name="code"></param>
        /// <param name="token"></param>
        /// <returns></returns>
        public async Task<IActionResult> RemoteBuild([FromRoute]string code, [FromRoute]string token)
        {
            var project = projectManager.GetProject(code, token);
            if(project.IsBuildRemote)
            {
                workManager.StartWork(project.Id);
                return new JsonResult(new Output
                {
                    code = 1
                });
            }
            return new JsonResult(new Output
            {
                code = 1,
                msg="未启用远程构建"
            });
        }

        [HttpPost]
        public async Task<IActionResult> DeleteProject(int projectid)
        {
            var project = projectManager.GetProject(projectid);
            workManager.RemoveWorkspace(project);
            projectManager.RemoveProject(projectid);
            return new JsonResult(new Output
            {
                code = 1
            });
        }

        [HttpGet]
        public async Task<IActionResult> GetBuildlogs(int projectid, int pageindex, int pagesize)
        {
            var pageResult = projectManager.GetBuildLogs(projectid, pageindex, pagesize);
            return new JsonResult(new Output<PaggingEntity<BuildLog>>
            {
                code = 1,
                data = pageResult
            });
        }
        [HttpGet]
        public async Task<IActionResult> GetBuildlog(string buildlogid)
        {
            var log = projectManager.GetBuildLog(buildlogid);
            if (log.BuildState == BuildLog.BuildStateEnum.Building)
            {
                log.OutContent = iOManager.DequeueOutput(log.GetIOKey());
            }
            return new JsonResult(new Output<BuildLog>
            {
                code = 1,
                data = log
            });
        }

        [HttpGet]
        public async Task<IActionResult> BuildLogDetails(string buildlogid)
        {
            var buildlog= projectManager.GetBuildLog(buildlogid);

            var clientid = string.Empty;
            if(string.IsNullOrEmpty(HttpContext.Request.Cookies["clientid"]))
            {
                clientid = Guid.NewGuid().ToString();
                HttpContext.Response.Cookies.Append("clientid", clientid, new CookieOptions() { IsEssential = true });
            }
            else
            {
                clientid = HttpContext.Request.Cookies["clientid"];
            }


            //往输出管道注册输出处理
            iOManager.AddEventHandler(iOManager.GetDefaultIOEnventHandler(clientid, buildlog.GetIOKey(), ouput => {
                iohub.Clients.All.SendAsync("ReceiveBuildMessage", buildlog.GetIOKey(), ouput);
            }, IIOEnventHandler.EventTypeEnum.Output));

            ViewBag.BuildLog = buildlog;
            return View();
        }
        [HttpPost]
        public async Task<IActionResult> DeleteBuildLog(string buildlogid)
        {
            projectManager.RemoveBuildLog(buildlogid);
            return new JsonResult(new Output
            {
                code = 1
            });
        }
        [HttpPost]
        public async Task<IActionResult> SendBuildInput(string buildlogid, string content)
        {
            var log = projectManager.GetBuildLog(buildlogid);
            iOManager.EnqueueInput(log.GetIOKey(), content);
            return new JsonResult(new Output
            {
                code = 1
            });
        }


    }
}